package com.hqd.ch03.v51.boot;

import com.hqd.ch03.v51.context.ApplicationListener;

import java.util.function.Supplier;

/**
 * 引导时仓库
 */
public interface BootstrapRegistry {

    <T> void register(Class<T> type, InstanceSupplier<T> instanceSupplier);

    <T> void registerIfAbsent(Class<T> type, InstanceSupplier<T> instanceSupplier);

    <T> boolean isRegistered(Class<T> type);

    <T> InstanceSupplier<T> getRegisteredInstanceSupplier(Class<T> type);

    void addCloseListener(ApplicationListener<BootstrapContextClosedEvent> listener);

    enum Scope {
        SINGLETON,
        PROTOTYPE
    }

    @FunctionalInterface
    interface InstanceSupplier<T> {

        static <T> InstanceSupplier<T> of(T instance) {
            return (registry) -> instance;
        }

        static <T> InstanceSupplier<T> from(Supplier<T> supplier) {
            return (registry) -> (supplier != null) ? supplier.get() : null;
        }

        T get(BootstrapContext context);

        default Scope getScope() {
            return Scope.SINGLETON;
        }

        default InstanceSupplier<T> withScope(Scope scope) {
            InstanceSupplier<T> parent = this;
            return new InstanceSupplier<T>() {

                @Override
                public T get(BootstrapContext context) {
                    return parent.get(context);
                }

                @Override
                public Scope getScope() {
                    return scope;
                }

            };
        }

    }

}
